import React, { useState, useRef, useEffect } from 'react';
import './Tooltip.css';

const Tooltip = ({
  children,
  content,
  position = 'top',
  className = '',
  style = {},
  arrow = true,
  maxWidth = '200px',
  delay = 300,
  offset = 10,
  disabled = false,
  trigger = 'hover',
  visible: controlledVisible,
  onVisibleChange,
  backgroundColor = 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
  textColor = '#ffffff',
  fontSize = '12px',
  padding = '8px 12px',
  borderRadius = '8px',
  zIndex = 1000,
  ...props
}) => {
  const [internalVisible, setInternalVisible] = useState(false);
  const [tooltipStyle, setTooltipStyle] = useState({});
  const tooltipRef = useRef(null);
  const triggerRef = useRef(null);
  const hoverTimeoutRef = useRef(null);

  const isControlled = controlledVisible !== undefined;
  const visible = isControlled ? controlledVisible : internalVisible;

  const showTooltip = () => {
    if (disabled) return;
    
    if (hoverTimeoutRef.current) {
      clearTimeout(hoverTimeoutRef.current);
    }
    
    hoverTimeoutRef.current = setTimeout(() => {
      if (!isControlled) {
        setInternalVisible(true);
      }
      onVisibleChange?.(true);
      calculatePosition();
    }, delay);
  };

  const hideTooltip = () => {
    if (hoverTimeoutRef.current) {
      clearTimeout(hoverTimeoutRef.current);
    }
    
    hoverTimeoutRef.current = setTimeout(() => {
      if (!isControlled) {
        setInternalVisible(false);
      }
      onVisibleChange?.(false);
    }, 100);
  };

  const calculatePosition = () => {
    if (!triggerRef.current || !tooltipRef.current) return;

    const triggerRect = triggerRef.current.getBoundingClientRect();
    const tooltipRect = tooltipRef.current.getBoundingClientRect();
    const viewportWidth = window.innerWidth;
    const viewportHeight = window.innerHeight;

    let top = 0;
    let left = 0;
    let finalPosition = position;

    // Calculate base position based on desired position
    switch (position) {
      case 'top':
        top = triggerRect.top - tooltipRect.height - offset;
        left = triggerRect.left + (triggerRect.width - tooltipRect.width) / 2;
        break;
      case 'bottom':
        top = triggerRect.bottom + offset;
        left = triggerRect.left + (triggerRect.width - tooltipRect.width) / 2;
        break;
      case 'left':
        top = triggerRect.top + (triggerRect.height - tooltipRect.height) / 2;
        left = triggerRect.left - tooltipRect.width - offset;
        break;
      case 'right':
        top = triggerRect.top + (triggerRect.height - tooltipRect.height) / 2;
        left = triggerRect.right + offset;
        break;
      default:
        top = triggerRect.top - tooltipRect.height - offset;
        left = triggerRect.left + (triggerRect.width - tooltipRect.width) / 2;
    }

    // Adjust position if tooltip goes outside viewport
    if (left < 10) {
      left = 10;
    } else if (left + tooltipRect.width > viewportWidth - 10) {
      left = viewportWidth - tooltipRect.width - 10;
    }

    if (top < 10) {
      // If top position goes above viewport, switch to bottom
      if (position === 'top') {
        finalPosition = 'bottom';
        top = triggerRect.bottom + offset;
      } else {
        top = 10;
      }
    } else if (top + tooltipRect.height > viewportHeight - 10) {
      // If bottom position goes below viewport, switch to top
      if (position === 'bottom') {
        finalPosition = 'top';
        top = triggerRect.top - tooltipRect.height - offset;
      } else {
        top = viewportHeight - tooltipRect.height - 10;
      }
    }

    setTooltipStyle({
      top: `${top}px`,
      left: `${left}px`,
      maxWidth,
      background: backgroundColor,
      color: textColor,
      fontSize,
      padding,
      borderRadius,
      zIndex,
      ...style
    });

    return finalPosition;
  };

  useEffect(() => {
    if (visible) {
      calculatePosition();
      window.addEventListener('scroll', calculatePosition);
      window.addEventListener('resize', calculatePosition);
      
      return () => {
        window.removeEventListener('scroll', calculatePosition);
        window.removeEventListener('resize', calculatePosition);
      };
    }
  }, [visible, position, offset, maxWidth]);

  useEffect(() => {
    return () => {
      if (hoverTimeoutRef.current) {
        clearTimeout(hoverTimeoutRef.current);
      }
    };
  }, []);

  const getArrowClass = () => {
    if (!arrow) return '';
    
    const baseClass = 'tooltip-arrow';
    const positionClass = `tooltip-arrow-${position}`;
    
    return `${baseClass} ${positionClass}`;
  };

  const getTooltipClass = () => {
    const baseClass = 'tooltip';
    const positionClass = `tooltip-${position}`;
    const visibleClass = visible ? 'tooltip-visible' : '';
    
    return `${baseClass} ${positionClass} ${visibleClass} ${className}`.trim();
  };

  const triggerProps = {};
  
  if (trigger === 'hover' && !disabled) {
    triggerProps.onMouseEnter = showTooltip;
    triggerProps.onMouseLeave = hideTooltip;
  } else if (trigger === 'click' && !disabled) {
    triggerProps.onClick = () => {
      if (visible) {
        hideTooltip();
      } else {
        showTooltip();
      }
    };
  }

  return (
    <>
      <div 
        ref={triggerRef}
        className="tooltip-trigger"
        {...triggerProps}
        {...props}
      >
        {children}
      </div>
      
      {visible && content && (
        <div
          ref={tooltipRef}
          className={getTooltipClass()}
          style={tooltipStyle}
          role="tooltip"
          aria-hidden={!visible}
        >
          {arrow && <div className={getArrowClass()} />}
          <div className="tooltip-content">
            {content}
          </div>
        </div>
      )}
    </>
  );
};

export default Tooltip;